package com.roger.homecenterscreen.data.repository

import com.roger.homecenterscreen.data.api.WeatherApiService
import com.roger.homecenterscreen.data.api.QWeatherNow
import com.roger.homecenterscreen.data.api.QWeatherHourly
import com.roger.homecenterscreen.data.api.QWeatherDaily
import com.roger.homecenterscreen.data.api.QWeatherAir
import com.roger.homecenterscreen.data.model.WeatherData
import com.roger.homecenterscreen.data.model.CurrentWeather
import com.roger.homecenterscreen.data.model.HourlyWeather
import com.roger.homecenterscreen.data.model.DailyForecast
import com.roger.homecenterscreen.data.model.AirQuality
import com.roger.homecenterscreen.data.model.WeatherLocation
import com.roger.homecenterscreen.data.location.LocationData
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.withContext
import com.roger.homecenterscreen.config.ApiConfig
import android.util.Log
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import java.util.TimeZone

class WeatherRepository(
    private val weatherApi: WeatherApiService
) {
    
    companion object {
        private const val TAG = "WeatherRepository"
    }
    
    private val apiKey = ApiConfig.QWEATHER_API_KEY
    // 固定使用佛山南海区的位置信息
    private var currentLocation = ApiConfig.DEFAULT_LOCATION
    private var locationDisplayInfo: WeatherLocation = WeatherLocation(
        city = "佛山",
        district = "南海区", 
        country = "中国"
    )
    
    /**
     * 设置当前位置
     * @param location 位置，可以是城市代码或经纬度格式
     */
    fun setLocation(location: String) {
        currentLocation = location
    }
    
    /**
     * 设置位置显示信息（从LocationData获取）
     * 注意：现在固定使用佛山南海区，此方法主要用于保持兼容性
     * @param locationData 位置数据对象
     */
    fun setLocationData(locationData: LocationData) {
        Log.i(TAG, "🏠 收到位置数据，但使用固定的佛山南海区位置")
        Log.i(TAG, "   传入位置: ${locationData.getDisplayName()}")
        Log.i(TAG, "   实际使用: 佛山 南海区")
        
        // 固定使用佛山的城市代码和经纬度
        currentLocation = "113.1617,23.0268" // 佛山南海区的经纬度格式
        
        // 位置信息已经在初始化时设置为佛山南海区
        // locationDisplayInfo 保持不变
    }
    
    suspend fun getWeatherData(): Result<WeatherData> = withContext(Dispatchers.IO) {
        try {
            Log.i(TAG, "🌤️ =============== 开始获取天气数据 ===============")
            Log.i(TAG, "📍 使用位置: $currentLocation")
            
            // 检查网络连接状态（这里可以添加更详细的网络检查）
            // 目前依赖API调用的异常处理
            
            // 并发请求所有天气数据 - 使用逐小时预报作为主要数据源
            val hourlyWeatherDeferred = async { 
                Log.i(TAG, "📡 请求逐小时天气预报...")
                weatherApi.getHourlyWeather(currentLocation, apiKey) 
            }
            val dailyWeatherDeferred = async { 
                Log.i(TAG, "📡 请求每日天气预报...")
                weatherApi.getDailyWeather(currentLocation, apiKey) 
            }
            val airQualityDeferred = async { 
                Log.i(TAG, "📡 请求空气质量数据...")
                weatherApi.getAirQuality(currentLocation, apiKey) 
            }
            
            val hourlyWeatherResponse = hourlyWeatherDeferred.await()
            val dailyWeatherResponse = dailyWeatherDeferred.await()
            val airQualityResponse = airQualityDeferred.await()
            
            Log.i(TAG, "📊 API响应状态:")
            Log.i(TAG, "   🕐 逐小时预报: ${if (hourlyWeatherResponse.isSuccessful) "✅成功" else "❌失败(${hourlyWeatherResponse.code()})"}")
            Log.i(TAG, "   📅 每日预报: ${if (dailyWeatherResponse.isSuccessful) "✅成功" else "❌失败(${dailyWeatherResponse.code()})"}")
            Log.i(TAG, "   🌫️ 空气质量: ${if (airQualityResponse.isSuccessful) "✅成功" else "❌失败(${airQualityResponse.code()})"}")
            
            // 检查关键响应是否成功
            if (!hourlyWeatherResponse.isSuccessful || !dailyWeatherResponse.isSuccessful) {
                Log.e(TAG, "❌ 关键天气数据请求失败")
                return@withContext Result.failure(Exception("关键天气数据请求失败"))
            }
            
            val hourlyWeatherData = hourlyWeatherResponse.body()
            val dailyWeatherData = dailyWeatherResponse.body()
            val airQualityData = airQualityResponse.body()
            
            Log.i(TAG, "📋 API响应代码:")
            Log.i(TAG, "   🕐 逐小时: ${hourlyWeatherData?.code}")
            Log.i(TAG, "   📅 每日: ${dailyWeatherData?.code}")
            Log.i(TAG, "   🌫️ 空气: ${airQualityData?.code}")
            
            if (hourlyWeatherData?.code != "200" || dailyWeatherData?.code != "200") {
                Log.e(TAG, "❌ 天气API返回错误代码")
                return@withContext Result.failure(Exception("天气API返回错误代码"))
            }
            
            // 使用逐小时预报的第一个数据作为当前天气
            if (hourlyWeatherData.hourly.isEmpty()) {
                Log.e(TAG, "❌ 逐小时天气数据为空")
                return@withContext Result.failure(Exception("逐小时天气数据为空"))
            }
            
            val currentHourWeather = hourlyWeatherData.hourly.first()
            Log.i(TAG, "🎯 使用逐小时预报第一项作为当前天气:")
            Log.i(TAG, "   ⏰ 时间: ${currentHourWeather.fxTime}")
            Log.i(TAG, "   🌡️ 温度: ${currentHourWeather.temp}°C")
            Log.i(TAG, "   🌤️ 天气: ${currentHourWeather.text}")
            Log.i(TAG, "   💧 降水概率: ${currentHourWeather.pop}%")
            
            // 分别处理今天的数据和未来的数据
            val (todaySummary, futureForecast) = processDailyForecastData(dailyWeatherData.daily)
            
            val weatherData = WeatherData(
                currentWeather = convertHourlyToCurrentWeather(currentHourWeather),
                todayHourly = convertHourlyWeather(hourlyWeatherData.hourly),
                todaySummary = todaySummary, // 今天的天气总结
                forecast = futureForecast, // 未来天气（不包含今天）
                airQuality = if (airQualityResponse.isSuccessful && airQualityData?.code == "200") {
                    convertAirQuality(airQualityData.now)
                } else {
                    getDefaultAirQuality() // 空气质量数据获取失败时使用默认值
                },
                location = locationDisplayInfo // 始终使用佛山南海区
            )
            
            Log.i(TAG, "✅ 天气数据处理完成")
            Log.i(TAG, "🌤️ =============== 天气数据获取成功 ===============")
            Result.success(weatherData)
        } catch (e: java.net.UnknownHostException) {
            Log.e(TAG, "🌐 网络连接失败 - DNS解析异常", e)
            Log.e(TAG, "🌤️ =============== 天气数据获取失败 (无网络) ===============")
            Result.failure(Exception("网络不可用，无法获取天气数据", e))
        } catch (e: java.net.ConnectException) {
            Log.e(TAG, "🌐 网络连接失败 - 连接超时", e)
            Log.e(TAG, "🌤️ =============== 天气数据获取失败 (连接超时) ===============")
            Result.failure(Exception("网络连接超时，请检查网络状态", e))
        } catch (e: java.io.IOException) {
            Log.e(TAG, "🌐 网络IO异常", e)
            Log.e(TAG, "🌤️ =============== 天气数据获取失败 (网络异常) ===============")
            Result.failure(Exception("网络异常，无法获取天气数据", e))
        } catch (e: Exception) {
            Log.e(TAG, "💥 天气数据获取异常", e)
            Log.e(TAG, "🌤️ =============== 天气数据获取失败 ===============")
            Result.failure(Exception("天气数据获取失败: ${e.message}", e))
        }
    }
    
    /**
     * 将逐小时天气数据转换为当前天气数据
     * 使用逐小时预报的第一个数据作为当前天气，提供更丰富的信息
     */
    private fun convertHourlyToCurrentWeather(qWeatherHourly: QWeatherHourly): CurrentWeather {
        Log.i(TAG, "🔄 转换逐小时数据为当前天气:")
        Log.i(TAG, "   输入数据: ${qWeatherHourly.temp}°C, ${qWeatherHourly.text}, 湿度${qWeatherHourly.humidity}%")
        
        val currentWeather = CurrentWeather(
            temperature = qWeatherHourly.temp.toIntOrNull() ?: 0,
            feelsLike = qWeatherHourly.temp.toIntOrNull() ?: 0, // 逐小时API没有体感温度，使用实际温度
            humidity = qWeatherHourly.humidity.toIntOrNull() ?: 0,
            pressure = qWeatherHourly.pressure.toIntOrNull() ?: 0,
            visibility = 10, // 逐小时API没有能见度，使用默认值
            uvIndex = 5, // 逐小时API没有UV指数，使用默认值
            windSpeed = qWeatherHourly.windSpeed.toIntOrNull() ?: 0,
            windDirection = qWeatherHourly.windDir,
            weatherCode = convertWeatherIcon(qWeatherHourly.icon),
            weatherDesc = qWeatherHourly.text,
            icon = qWeatherHourly.icon
        )
        
        Log.i(TAG, "   转换结果: ${currentWeather.temperature}°C, ${currentWeather.weatherDesc}")
        return currentWeather
    }
    
    /**
     * 保留原始方法以备需要
     */
    private fun convertCurrentWeather(qWeatherNow: QWeatherNow): CurrentWeather {
        return CurrentWeather(
            temperature = qWeatherNow.temp.toIntOrNull() ?: 0,
            feelsLike = qWeatherNow.feelsLike.toIntOrNull() ?: 0,
            humidity = qWeatherNow.humidity.toIntOrNull() ?: 0,
            pressure = qWeatherNow.pressure.toIntOrNull() ?: 0,
            visibility = qWeatherNow.vis.toIntOrNull() ?: 0,
            uvIndex = 5, // 和风天气免费版不包含UV指数
            windSpeed = qWeatherNow.windSpeed.toIntOrNull() ?: 0,
            windDirection = qWeatherNow.windDir,
            weatherCode = convertWeatherIcon(qWeatherNow.icon),
            weatherDesc = qWeatherNow.text,
            icon = qWeatherNow.icon
        )
    }
    
    private fun convertHourlyWeather(qWeatherHourly: List<QWeatherHourly>): List<HourlyWeather> {
        Log.i(TAG, "🔄 开始转换逐小时天气数据，共${qWeatherHourly.size}条记录")
        
        return qWeatherHourly.take(12).mapIndexed { index, hourly ->
            val formattedTime = formatTime(hourly.fxTime)
            Log.i(TAG, "   📊 [${index + 1}] 原始时间: '${hourly.fxTime}' -> 格式化: '$formattedTime'")
            
            HourlyWeather(
                time = formattedTime,
                temperature = hourly.temp.toIntOrNull() ?: 0,
                weatherCode = convertWeatherIcon(hourly.icon),
                weatherDesc = hourly.text,
                icon = hourly.icon,
                precipitation = hourly.pop.toIntOrNull() ?: 0
            )
        }.also {
            Log.i(TAG, "✅ 逐小时天气数据转换完成，生成${it.size}条记录")
        }
    }
    
    /**
     * 处理每日预报数据，分离今天和未来的数据
     * @return Pair<今天的天气总结, 未来天气列表>
     */
    private fun processDailyForecastData(qWeatherDaily: List<QWeatherDaily>): Pair<DailyForecast?, List<DailyForecast>> {
        Log.i(TAG, "🔄 开始处理每日预报数据，原始数据${qWeatherDaily.size}条")
        
        var todaySummary: DailyForecast? = null
        val futureDays = mutableListOf<QWeatherDaily>()
        
        // 分离今天和未来的数据
        qWeatherDaily.forEach { daily ->
            val dayOfWeek = getDayOfWeek(daily.fxDate)
            val isToday = dayOfWeek == "今天"
            Log.i(TAG, "   📅 日期: ${daily.fxDate} -> $dayOfWeek ${if (isToday) "(今天总结)" else "(未来天气)"}")
            
            if (isToday) {
                todaySummary = convertToDailyForecast(daily)
                Log.i(TAG, "   📊 今天总结: ${daily.tempMin}°-${daily.tempMax}°, ${daily.textDay}")
            } else {
                futureDays.add(daily)
            }
        }
        
        val futureForecast = futureDays.take(3).map { daily ->
            convertToDailyForecast(daily)
        }
        
        Log.i(TAG, "✅ 每日预报数据处理完成:")
        Log.i(TAG, "   📅 今天总结: ${if (todaySummary != null) "已获取" else "无数据"}")
        Log.i(TAG, "   📅 未来天气: ${futureForecast.size}条记录")
        
        return Pair(todaySummary, futureForecast)
    }
    
    /**
     * 转换单个每日天气数据
     */
    private fun convertToDailyForecast(daily: QWeatherDaily): DailyForecast {
        return DailyForecast(
            date = formatDate(daily.fxDate),
            dayOfWeek = getDayOfWeek(daily.fxDate),
            maxTemp = daily.tempMax.toIntOrNull() ?: 0,
            minTemp = daily.tempMin.toIntOrNull() ?: 0,
            weatherCode = convertWeatherIcon(daily.iconDay),
            weatherDesc = daily.textDay,
            icon = daily.iconDay,
            precipitation = 0 // 和风天气免费版降水概率需要从其他字段获取
        )
    }
    
    private fun convertAirQuality(qWeatherAir: QWeatherAir): AirQuality {
        Log.i(TAG, "🔄 转换空气质量数据: AQI=${qWeatherAir.aqi}, 等级=${qWeatherAir.category}")
        
        return AirQuality(
            aqi = qWeatherAir.aqi.toIntOrNull() ?: 0,
            level = qWeatherAir.category,
            pm25 = qWeatherAir.pm2p5.toIntOrNull() ?: 0,
            pm10 = qWeatherAir.pm10.toIntOrNull() ?: 0,
            so2 = qWeatherAir.so2.toIntOrNull() ?: 0,
            no2 = qWeatherAir.no2.toIntOrNull() ?: 0,
            co = qWeatherAir.co.toFloatOrNull() ?: 0f,
            o3 = qWeatherAir.o3.toIntOrNull() ?: 0
        )
    }
    
    /**
     * 获取默认空气质量数据（当空气质量API失败时使用）
     */
    private fun getDefaultAirQuality(): AirQuality {
        Log.i(TAG, "🔄 使用默认空气质量数据")
        
        return AirQuality(
            aqi = 50,
            level = "良",
            pm25 = 25,
            pm10 = 50,
            so2 = 10,
            no2 = 20,
            co = 0.5f,
            o3 = 80
        )
    }
    
    private fun convertWeatherIcon(icon: String): String {
        // 和风天气图标代码转换为内部代码
        return when (icon) {
            "100" -> "sunny"           // 晴
            "101", "102", "103" -> "partly_cloudy"  // 多云
            "104" -> "cloudy"          // 阴
            "300", "301", "302", "303", "304" -> "rainy"  // 雨
            "400", "401", "402", "403", "404" -> "snowy"  // 雪
            "302", "303", "304" -> "thunderstorm"  // 雷阵雨
            "500", "501", "502", "503", "504", "507", "508" -> "foggy"  // 雾
            else -> "sunny"
        }
    }
    
    private fun formatTime(fxTime: String): String {
        Log.i(TAG, "🕐 解析时间字符串: '$fxTime'")
        
        return try {
            // 和风天气API返回的时间格式没有秒数：2025-07-21T01:00+08:00
            val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mmXXX", Locale.getDefault())
            val outputFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
            val date = inputFormat.parse(fxTime)
            val result = outputFormat.format(date ?: return "00:00")
            Log.i(TAG, "✅ 时间解析成功: '$fxTime' -> '$result'")
            result
        } catch (e: Exception) {
            Log.w(TAG, "❌ 时间解析失败: '$fxTime', 错误: ${e.message}")
            Log.w(TAG, "🔄 尝试备用解析方法...")
            
            // 备用解析方法：使用正则表达式提取时间
            try {
                val timeRegex = Regex("T(\\d{2}):(\\d{2})")
                val matchResult = timeRegex.find(fxTime)
                if (matchResult != null) {
                    val hour = matchResult.groupValues[1]
                    val minute = matchResult.groupValues[2]
                    val result = "$hour:$minute"
                    Log.i(TAG, "✅ 备用解析成功: '$fxTime' -> '$result'")
                    result
                } else {
                    Log.w(TAG, "❌ 备用解析也失败，返回默认值")
                    "00:00"
                }
            } catch (regexException: Exception) {
                Log.w(TAG, "❌ 正则解析异常: ${regexException.message}")
                "00:00"
            }
        }
    }
    
    private fun formatDate(fxDate: String): String {
        return try {
            val inputFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
            val outputFormat = SimpleDateFormat("MM-dd", Locale.getDefault())
            val date = inputFormat.parse(fxDate)
            outputFormat.format(date ?: return "")
        } catch (e: Exception) {
            ""
        }
    }
    
    private fun getDayOfWeek(fxDate: String): String {
        return try {
            val chinaTimeZone = TimeZone.getTimeZone("Asia/Shanghai")
            val inputFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).apply {
                timeZone = chinaTimeZone
            }
            val date = inputFormat.parse(fxDate)
            val calendar = Calendar.getInstance(chinaTimeZone)
            calendar.time = date ?: return ""
            
            val today = Calendar.getInstance(chinaTimeZone)
            
            // 使用日期比较而不是毫秒差值，避免时区问题
            val dateYear = calendar.get(Calendar.YEAR)
            val dateMonth = calendar.get(Calendar.MONTH)
            val dateDayOfYear = calendar.get(Calendar.DAY_OF_YEAR)
            
            val todayYear = today.get(Calendar.YEAR)
            val todayMonth = today.get(Calendar.MONTH)
            val todayDayOfYear = today.get(Calendar.DAY_OF_YEAR)
            
            val diffDays = when {
                dateYear == todayYear -> dateDayOfYear - todayDayOfYear
                dateYear == todayYear + 1 && dateMonth == Calendar.JANUARY && todayMonth == Calendar.DECEMBER -> {
                    // 跨年情况：明年1月 - 今年12月
                    dateDayOfYear + (if (isLeapYear(todayYear)) 366 else 365) - todayDayOfYear
                }
                else -> Int.MAX_VALUE // 其他情况作为远期日期处理
            }
            
            when (diffDays) {
                0 -> "今天"
                1 -> "明天"
                2 -> "后天"
                else -> {
                    val weekFormat = SimpleDateFormat("EEEE", Locale.CHINA).apply {
                        timeZone = chinaTimeZone
                    }
                    weekFormat.format(date)
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "日期解析异常: $fxDate", e)
            ""
        }
    }
    
    /**
     * 判断是否为闰年
     */
    private fun isLeapYear(year: Int): Boolean {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
    }
    
    /**
     * 根据位置信息获取城市名称
     */
    private fun getLocationInfo(location: String): WeatherLocation {
        // 如果传入的是LocationData的显示名称，直接使用
        if (!location.contains(",") && !location.matches(Regex("\\d+"))) {
            return WeatherLocation(location)
        }
        return when {
            // 如果是经纬度格式 "116.4074,39.9042"
            location.contains(",") -> {
                val coords = location.split(",")
                if (coords.size == 2) {
                    val lon = coords[0].toDoubleOrNull()
                    val lat = coords[1].toDoubleOrNull()
                    if (lon != null && lat != null) {
                        // 根据经纬度大致判断城市（简化版本）
                        getCityByCoordinates(lat, lon)
                    } else {
                        WeatherLocation("未知位置")
                    }
                } else {
                    WeatherLocation("位置解析错误")
                }
            }
            // 如果是城市代码
            else -> {
                getCityByCode(location)
            }
        }
    }
    
    /**
     * 根据经纬度获取城市信息（简化版本）
     * 注意：这个方法应该尽量少用，优先使用EnhancedLocationService的cn.apihz.cn API结果
     */
    private fun getCityByCoordinates(lat: Double, lon: Double): WeatherLocation {
        // 不再使用粗糙的坐标范围判断，直接返回坐标信息
        // 让EnhancedLocationService通过cn.apihz.cn API获取准确地址
        return WeatherLocation(
            city = "坐标定位",
            district = String.format("%.4f°N,%.4f°E", lat, lon),
            country = "中国"
        )
    }
    
    /**
     * 根据城市代码获取城市信息
     */
    private fun getCityByCode(cityCode: String): WeatherLocation {
        return when (cityCode) {
            "101010100" -> WeatherLocation("北京", "海淀区")
            "101020100" -> WeatherLocation("上海", "浦东新区")
            "101280101" -> WeatherLocation("广州", "天河区")
            "101280601" -> WeatherLocation("深圳", "南山区")
            "101280801" -> WeatherLocation("佛山", "南海区")  // 添加佛山市南海区
            "101210101" -> WeatherLocation("杭州", "西湖区")
            "101200101" -> WeatherLocation("武汉", "江汉区")
            "101190401" -> WeatherLocation("南京", "玄武区")
            "101270101" -> WeatherLocation("成都", "锦江区")
            "101040100" -> WeatherLocation("重庆", "渝中区")
            else -> WeatherLocation("其他城市", cityCode)
        }
    }
} 